﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Diagnostics;
using Oracle.DataAccess.Client;

namespace CallVertex
{
    public class myFavEx : Exception
    {
        public myFavEx() { }
        public myFavEx(string message):base(message) { }
        public myFavEx(string message, Exception inner) : base(message,inner) { }
    }
    public class SalesTaxCalc
    {
        #region structures
        public struct _addressRecord 
        { 

           private string geocode;
           private string city;
           private string country;
           private string state;
           private string zipcode;
           private string errormsg;
           public string City { get { return city; } set { city = value; } }
           public string County { get { return country; } set { country = value; } }
           public string State { get { return state; } set { state = value; } }
           public string ZipCode { get { return zipcode; } set { zipcode = value; } }
           public string GeoCode
           {
               get { return geocode; }
               set { geocode = value; }
           }
           public string ErrorMsg { get { return errormsg; } set { errormsg = value; } }
           public Dictionary<int, _addressRecord> DictionaryofAddresses; 
        }
        #endregion structures
        #region properties
        const string MyVertexCallsSource = "MyVertexCalls";
        private string _CustomerId;
        private string _ProductCode;
        private uint _fromGeocode;
        private uint _toGeoCode;
        private double _amount;
        private OracleConnection _oConnection;

        public string CustomerId
        {
            get { return _CustomerId; }
            set { _CustomerId = value; }
        }

        public string ProductCode
        {
            get { return _ProductCode; }
            set { _ProductCode = value; }
        }

        public uint fromGeocode
        {
            get { return _fromGeocode; }
            set { _fromGeocode = value; }
        }

        public uint toGeoCode
        {
            get { return _toGeoCode; }
            set { _toGeoCode = value; }
        }

        public double amount
        {
            get { return _amount; }
            set { _amount = value; }
        }

        public OracleConnection oConnection
        {
            get { return _oConnection; }
            set { _oConnection = value; }
        }
        
        #endregion properties
        #region constructor
        public SalesTaxCalc()
        {
            //do nothing.

        }
        #endregion constructor
        #region functions
        public string getVertexVersion(string vertexSeries, OracleConnection oConnection)
            {
                string VertexVersion="";
                OracleCommand ocgetVertexVersion;
                try
                {
                    ocgetVertexVersion = new OracleCommand();
                    ocgetVertexVersion.Connection = _oConnection;
                    
                    ocgetVertexVersion.CommandText = "ge_tax.sp_get_vertex_version";
                    ocgetVertexVersion.CommandType = System.Data.CommandType.StoredProcedure;

                    OracleParameter ocVertexSeries = new OracleParameter("v_qsu_or_geo", OracleDbType.Varchar2, 3);
                    ocVertexSeries.Value = vertexSeries;
                    ocVertexSeries.Direction = ParameterDirection.Input;
                    ocgetVertexVersion.Parameters.Add(ocVertexSeries);

                    OracleParameter ocVertexVersion = new OracleParameter("v_version", OracleDbType.Varchar2, 6);
                    ocVertexVersion.Direction = ParameterDirection.Output;
                    ocgetVertexVersion.Parameters.Add(ocVertexVersion);

                    OracleParameter ocReturnErrorMessage = new OracleParameter("r_errormessage", OracleDbType.Varchar2, 200);
                    ocReturnErrorMessage.Direction = ParameterDirection.Output;
                    ocgetVertexVersion.Parameters.Add(ocReturnErrorMessage);

                    OracleParameter ocReturnCode = new OracleParameter("r_returncode", OracleDbType.Int32, 5);
                    ocReturnCode.Direction = ParameterDirection.Output;
                    ocgetVertexVersion.Parameters.Add(ocReturnCode);

                    ocgetVertexVersion.ExecuteNonQuery();
                    VertexVersion = ocVertexVersion.Value.ToString();

                    Console.WriteLine(VertexVersion);
                    return VertexVersion;
                }
                catch (Exception e)
                {
                    return e.Message.ToString();
                }
            }

        public object ValidateAddress(string city,
                                      string county,
                                      string state,
                                      string postalcode)
        {
            ///ValidateAddress: This function returns a geocode for a valid address.
            ///
            _addressRecord Address = new _addressRecord();
            Dictionary<int, _addressRecord> DicAddress;
            OracleCommand ocGetGeocodeCount;
            OracleCommand ocGetGeocode;
            OracleParameter iCityName;
            OracleParameter iCountyName;
            OracleParameter iZipCode;
            OracleParameter iStateCode;
            OracleParameter oGeocodeCount;
            OracleParameter oReturnCode;
            OracleParameter iRecordNo;
            OracleParameter oCityName;
            OracleParameter oCountyName;
            OracleParameter oZipCodeStart;
            OracleParameter oZipCodeEnd;
            OracleParameter oStateCode;
            OracleParameter oGeoCode;
            OracleParameter oErrorMessage =new OracleParameter();
            int iKey;
            try
            {
                ocGetGeocodeCount = new OracleCommand();
                ocGetGeocodeCount.Connection = _oConnection;
                ocGetGeocodeCount.CommandText = "ge_tax.sp_get_geocode_count";
                ocGetGeocodeCount.CommandType = CommandType.StoredProcedure;
                DicAddress = new Dictionary<int, _addressRecord>();
                iStateCode = new OracleParameter();
                iStateCode.ParameterName = "iStateCode";
                iStateCode.OracleDbType = OracleDbType.Varchar2;
                iStateCode.Direction = ParameterDirection.Input;
                iStateCode.Size = 2;
                iStateCode.Value = state;
                ocGetGeocodeCount.Parameters.Add(iStateCode);

                iCountyName = new OracleParameter();
                iCountyName.ParameterName = "iCountyName";
                iCountyName.OracleDbType = OracleDbType.Varchar2;
                iCountyName.Direction = ParameterDirection.Input;
                iCountyName.Size = 50;
                iCountyName.Value = county;
                ocGetGeocodeCount.Parameters.Add(iCountyName);

                iCityName = new OracleParameter();
                iCityName.ParameterName = "iCityName";
                iCityName.OracleDbType = OracleDbType.Varchar2;
                iCityName.Direction = ParameterDirection.Input;
                iCityName.Size = 50;
                iCityName.Value = city;
                ocGetGeocodeCount.Parameters.Add(iCityName);

                iZipCode = new OracleParameter();
                iZipCode.ParameterName = "iZipCode";
                iZipCode.OracleDbType = OracleDbType.Varchar2;
                iZipCode.Direction = ParameterDirection.Input;
                iZipCode.Size = 10;
                iZipCode.Value = postalcode;
                ocGetGeocodeCount.Parameters.Add(iZipCode);

                oGeocodeCount = new OracleParameter();
                oGeocodeCount.ParameterName = "oGeocodeCount";
                oGeocodeCount.Direction = ParameterDirection.Output;
                oGeocodeCount.OracleDbType = OracleDbType.Int32;
                oGeocodeCount.Size = 10;
                ocGetGeocodeCount.Parameters.Add(oGeocodeCount);

                oErrorMessage = new OracleParameter();
                oErrorMessage.ParameterName = "oErrorMessage";
                oErrorMessage.Direction = ParameterDirection.Output;
                oErrorMessage.OracleDbType = OracleDbType.Varchar2;
                oErrorMessage.Size = 100;
                ocGetGeocodeCount.Parameters.Add(oErrorMessage);

                oReturnCode = new OracleParameter();
                oReturnCode.ParameterName = "oReturnCode";
                oReturnCode.Direction = ParameterDirection.Output;
                oReturnCode.OracleDbType = OracleDbType.Int32;
                oReturnCode.Size = 3;
                ocGetGeocodeCount.Parameters.Add(oReturnCode);
                ocGetGeocodeCount.ExecuteNonQuery();
                
                if (oReturnCode.Value.ToString() != "0")
                {
                    throw new myFavEx("Return Code is Zero");
                }
                
                iKey = (int) oGeocodeCount.Value;

                iCityName.Dispose();
                iStateCode.Dispose();
                iCountyName.Dispose();
                iZipCode.Dispose();
                oErrorMessage.Dispose();
                oReturnCode.Dispose();

                do{
                ocGetGeocode = new OracleCommand();
                ocGetGeocode.Connection = _oConnection;
                ocGetGeocode.CommandText = "ge_tax.sp_get_next_location";
                ocGetGeocode.CommandType = CommandType.StoredProcedure;
                
                iRecordNo = new OracleParameter();
                iRecordNo.OracleDbType = OracleDbType.Int32;
                iRecordNo.Direction = ParameterDirection.Input;
                iRecordNo.Value = iKey;
                iRecordNo.Size = 2;
                ocGetGeocode.Parameters.Add(iRecordNo);

                oCityName = new OracleParameter();
                oCityName.ParameterName = "oCityName";
                oCityName.OracleDbType = OracleDbType.Varchar2;
                oCityName.Direction = ParameterDirection.Output;
                oCityName.Size = 50;
                ocGetGeocode.Parameters.Add(oCityName);

               oCountyName = new OracleParameter();
                oCountyName.ParameterName = "oCountyName";
                oCountyName.OracleDbType = OracleDbType.Varchar2;
                oCountyName.Direction = ParameterDirection.Output;
                oCountyName.Size = 50;
                ocGetGeocode.Parameters.Add(oCountyName);

                oStateCode = new OracleParameter();
                oStateCode.ParameterName = "oStateCode";
                oStateCode.OracleDbType = OracleDbType.Varchar2;
                oStateCode.Direction = ParameterDirection.Output;
                oStateCode.Size = 2;
                ocGetGeocode.Parameters.Add(oStateCode);

                oZipCodeStart = new OracleParameter();
                oZipCodeStart.ParameterName = "oZipCodeStart";
                oZipCodeStart.OracleDbType = OracleDbType.Varchar2;
                oZipCodeStart.Direction = ParameterDirection.Output;
                oZipCodeStart.Size = 10;
                ocGetGeocode.Parameters.Add(oZipCodeStart);

                oZipCodeEnd = new OracleParameter();
                oZipCodeEnd.ParameterName = "oZipCodeEnd";
                oZipCodeEnd.OracleDbType = OracleDbType.Varchar2;
                oZipCodeEnd.Direction = ParameterDirection.Output;
                oZipCodeEnd.Size = 10;
                ocGetGeocode.Parameters.Add(oZipCodeEnd);


                oGeoCode = new OracleParameter();
                oGeoCode.ParameterName = "oGeocode";
                oGeoCode.Direction = ParameterDirection.Output;
                oGeoCode.OracleDbType = OracleDbType.Varchar2;
                oGeoCode.Size = 10;
                ocGetGeocode.Parameters.Add(oGeoCode);

                oErrorMessage = new OracleParameter();
                oErrorMessage.ParameterName = "oErrorMessage";
                oErrorMessage.Direction = ParameterDirection.Output;
                oErrorMessage.OracleDbType = OracleDbType.Varchar2;
                oErrorMessage.Size = 100;
                ocGetGeocode.Parameters.Add(oErrorMessage);

                oReturnCode = new OracleParameter();
                oReturnCode.ParameterName = "oReturnCode";
                oReturnCode.Direction = ParameterDirection.Output;
                oReturnCode.OracleDbType = OracleDbType.Int32;
                oReturnCode.Size = 3;
                ocGetGeocode.Parameters.Add(oReturnCode);
                ocGetGeocode.ExecuteNonQuery();

                if (oReturnCode.Value.ToString() != "0")
                {
                    throw new myFavEx(oErrorMessage.Value.ToString());
                }

                Address.City = oCityName.Value.ToString();
                Address.County = oCountyName.Value.ToString();
                Address.ZipCode = oZipCodeStart.Value.ToString();
                Address.State = oStateCode.Value.ToString();
                Address.GeoCode = oGeoCode.Value.ToString();

                //return oGeoCode.Value.ToString();
                DicAddress.Add(iKey,Address);
                iKey--;
                }while(iKey !=0);

                return DicAddress;

            }
            catch (Exception ex)
            {
                    EventLog.WriteEntry(MyVertexCallsSource, "Threw my custom exception", EventLogEntryType.Error, 100);
                    EventLog.WriteEntry(MyVertexCallsSource, ex.Message, EventLogEntryType.Error, 101);
                    Address.ErrorMsg = ex.Message.ToString();
                    return Address;
            }
            finally {
               // EventLog.WriteEntry(MyVertexCallsSource, oErrorMessage.Value.ToString(), EventLogEntryType.Error, 234);
            }
        }

        public object getVertexSalesTax(uint customeraccount, Single amount, char trantype) 
        {
            Dictionary<int,string> SalesTaxRecord;
            try
            {
                SalesTaxRecord = new Dictionary<int,string>();
                SalesTaxRecord.Add(1, "--");

                OracleCommand ocSetupTaxHeader = new OracleCommand();
                OracleParameter opCustomerNo;
                OracleParameter opInvoiceDate;
                OracleParameter opFromGeoCode;
                OracleParameter opToGeoCode;
                OracleParameter opWriteRegistryFlag;

                //Call SetupTaxHeader
                ocSetupTaxHeader.CommandText = "";
                ocSetupTaxHeader.CommandType = CommandType.StoredProcedure;
                ocSetupTaxHeader.Connection = _oConnection;
                opCustomerNo = new OracleParameter();
                opCustomerNo.Direction = ParameterDirection.Input;
                opCustomerNo.OracleDbType = OracleDbType.Int64;

                opInvoiceDate = new OracleParameter();
                opInvoiceDate.OracleDbType = OracleDbType.Date;
                opInvoiceDate.ParameterName = "";
                opInvoiceDate.Direction = ParameterDirection.Input;

                opFromGeoCode = new OracleParameter();
                opFromGeoCode.OracleDbType = OracleDbType.Int64;

                opToGeoCode = new OracleParameter();
                opToGeoCode.OracleDbType = OracleDbType.Int64;

                opWriteRegistryFlag = new OracleParameter();
                opWriteRegistryFlag.OracleDbType = OracleDbType.Varchar2;

                ocSetupTaxHeader.Parameters.Add(opCustomerNo);
                ocSetupTaxHeader.Parameters.Add(opInvoiceDate);
                ocSetupTaxHeader.Parameters.Add(opFromGeoCode);
                ocSetupTaxHeader.Parameters.Add(opToGeoCode);
                ocSetupTaxHeader.Parameters.Add(opWriteRegistryFlag);

                OracleCommand ocSetupTaxDetail = new OracleCommand();
                OracleCommand ocComputeTax = new OracleCommand();
                OracleCommand ocSalesTaxInvoice = new OracleCommand();


                return SalesTaxRecord;
            }
            catch (Exception ex)
            {
                
                throw ex;
            }
        }

        #endregion functions
    }
}	
